package server.utils;

import game.server.Game;
import server.ActiveSessions;

public class PlayerWatcher {

	private final Object lock;
	private int minPlayers;
	private ActiveSessions activeSessions;
	private Game game;
	/**
	 * Makes new playerWatcher with min players, active sessions and
	 * game.
	 * @param minPlayers Min players
	 * @param activeSessions Active sessions
	 * @param game Game to watch
	 */
	public PlayerWatcher(int minPlayers, ActiveSessions activeSessions,
			Game game) {
		lock = new Object();
		this.minPlayers = minPlayers;
		this.activeSessions = activeSessions;
		this.game = game;
	}
	/**
	 * Checks player count in game. If there are too few players puts
	 * game to stop.
	 */
	public void checkPlayerCount() {
		checkPlayerCount(true);
	}
	/**
	 * Checks player count in game.
	 * @param lock True if to lock game and players, false if not.
	 * @return True if conditions were true, false if not.
	 */
	private synchronized boolean checkPlayerCount(boolean locks) {
		int count;
		synchronized (activeSessions) {
			count = activeSessions.getActiveSessionsCount();
			if (locks) {
				if (count < minPlayers) {
					game.setRunning(false);
					return true;
				}
			} else {
				if (count >= minPlayers) {
					return true;
				}
			}
			return false;
		}
	}

	/**
	 * Notify all threads waiting at lock object.
	 */
	public synchronized void notifyGame() {
		if (checkPlayerCount(false)) {
			if (game.getStartLatch().isOpen() && !game.isRunning()) {
				synchronized (lock) {
					lock.notify();
				}
			}
		}
		
	}
	/**
	 * Wait for more player.
	 * @throws InterruptedException @ wait();
	 */
	public void waitForPlayers() throws InterruptedException {
		synchronized (lock) {
			lock.wait();
		} 
	}
	
}
